/*
 * $Id: $
 */
package org.rcgwt.client.ui.grid.controller;

import org.rcgwt.client.ui.grid.internal.model.IElementModel;
import org.rcgwt.client.ui.grid.internal.model.IStateMasks;
import org.rcgwt.client.ui.grid.internal.model.ITitleCellModel;
import org.rcgwt.client.ui.grid.internal.model.ITitleRowModel;
import org.rcgwt.client.ui.grid.internal.model.IViewModel;
import org.rcgwt.client.ui.grid.model.IGridWidget;
import org.rcgwt.client.ui.grid.provider.IOrderProvider;
import org.rcgwt.client.ui.grid.provider.IOverProvider;
import org.rcgwt.client.ui.grid.renderer.IGridRenderContext;
import org.rcgwt.client.ui.grid.renderer.ITitleCellRenderer;
import org.rcgwt.client.ui.grid.renderer.IViewRenderContext;

import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;

/**
 * 
 * @author Olivier Oeuillot (latest modification by $Author: $)
 * @version $Revision: $ $Date: $
 */
public class TitleCellEventController implements IElementModelEventController {

	private ITitleCellModel currentPushedTitleCell;

	private ITitleCellModel focusedTitleCell;

	@Override
	public boolean processFocus(IGridModelController gridModelController,
			IGridWidget gridWidget, IElementModel elementModel, Event event) {

		ITitleRowModel titleRowModel = null;

		switch (elementModel.getType()) {
		case TITLE_ROW:
			titleRowModel = (ITitleRowModel) elementModel;
			break;

		default:
			return false;
		}

		if (titleRowModel.isFocusable() == false) {
			// Can not happen !
			return false;
		}
		
		if (focusedTitleCell==null) {
		//	titleRowModel.getHeader().getViewModel().getViewModelElements().getTitleCellElement(titleCellModel)
		}
		

		ITitleCellModel titleCellModel = DefaultGridController
				.getTitleCellModel(elementModel);
		if (titleCellModel == null) {

			return false;
		}

		if (focusedTitleCell != null) {
			focusedTitleCell.updateStateMask(~IStateMasks.FOCUS_STATE_MASK,
					IStateMasks.FOCUS_STATE_MASK);
		}

		focusedTitleCell = titleCellModel;
		if (focusedTitleCell != null) {
			focusedTitleCell.updateStateMask(~IStateMasks.FOCUS_STATE_MASK, 0);
		}

		return true;
	}

	@Override
	public boolean processBlur(IGridModelController gridModelController,
			IGridWidget gridWidget, IElementModel elementModel, Event event) {
		return false;
	}

	@Override
	public boolean processOut(IGridModelController gridModelController,
			IGridWidget gridWidget, IElementModel elementModel, Event event) {

		IOverProvider overProvider = gridWidget.getOverProvider();

		if (overProvider == null) {
			return true;
		}

		overProvider.setOverElement(null);

		return true;
	}

	@Override
	public boolean processOver(IGridModelController gridModelController,
			IGridWidget gridWidget, IElementModel elementModel, Event event) {
		ITitleCellModel titleCellModel = DefaultGridController
				.getTitleCellModel(elementModel);
		if (titleCellModel == null) {
			return false;
		}

		IOverProvider overProvider = gridWidget.getOverProvider();
		if (overProvider == null) {
			return true;
		}

		overProvider.setOverElement(titleCellModel);

		return true;
	}

	@Override
	public boolean processKeyPress(IGridModelController gridModelController,
			IGridWidget gridWidget, IElementModel elementModel, Event event) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean processSelection(IGridModelController gridModelController,
			final IGridWidget gridWidget, IElementModel elementModel,
			final Event event) {
		ITitleCellModel titleCellModel = DefaultGridController
				.getTitleCellModel(elementModel);
		if (titleCellModel == null) {
			return false;
		}

		if (isPopupMarkerElement(gridWidget, titleCellModel, event)) {
			Window.alert("Show popup");
			return true;
		}

		processSelection(gridModelController, gridWidget, titleCellModel, event);

		return true;
	}

	protected void processSelection(IGridModelController gridModelController,
			IGridWidget gridWidget, ITitleCellModel titleCellModel, Event event) {

		if (titleCellModel.getColumnModel().getColumn().isSortable() == false) {
			return;
		}

		titleCellModel.updateStateMask(~IStateMasks.SELECTED_STATE_MASK,
				IStateMasks.SELECTED_STATE_MASK);

		currentPushedTitleCell = titleCellModel;

		gridModelController
				.setCaptureEventListener(new ICaptureEventListener() {

					@Override
					public boolean onBrowserEvent(
							IGridModelController gridModelController,
							IGridWidget gridWidget, IElementModel elementModel,
							Event event) {

						switch (event.getTypeInt()) {
						case Event.ONMOUSEUP:
							performColumnSort(gridWidget,
									currentPushedTitleCell, event);

							releasePushedTitleCell(gridWidget);
							gridModelController.releaseCapture(this);

							break;

						case Event.ONMOUSEOUT:
						case Event.ONMOUSEOVER:
							releasePushedTitleCell(gridWidget);

							gridModelController.releaseCapture(this);
							return true;

						default:
							break;
						}

						return false;
					}
				});
	}

	private boolean isPopupMarkerElement(IGridWidget gridWidget,
			ITitleCellModel titleCellModel, Event event) {

		IViewModel viewModel = DefaultGridController.getViewModel(gridWidget,
				event);

		IGridRenderContext gridRenderContext = gridWidget
				.getGridRenderContext();

		IViewRenderContext viewRenderContext = gridRenderContext
				.getViewRenderContext(viewModel);

		ITitleCellRenderer titleCellRenderer = gridRenderContext.getTheme()
				.getTitleCellRenderer(titleCellModel);

		Element targetElement = DOM.eventGetTarget(event);

		Element titleCellElement = viewModel.getViewModelElements()
				.getTitleCellElement(titleCellModel);

		boolean clicked = titleCellRenderer.isPopupMarkerClicked(
				viewRenderContext, titleCellModel, titleCellElement,
				targetElement);

		return clicked;
	}

	protected boolean isAppendMode(Event event) {
		return event.getCtrlKey();
	}

	protected boolean isRangeMode(Event event) {
		return event.getShiftKey();
	}

	private void performColumnSort(IGridWidget gridWidget,
			ITitleCellModel currentPushedTitleCell, Event event) {

		IOrderProvider orderProvider = gridWidget.getColumnsOrderProvider();
		if (orderProvider == null) {
			return;
		}

		int modelIndex = currentPushedTitleCell.getModelIndex();

		if (orderProvider.getOrderState(modelIndex) != null) {
			orderProvider.changeOrderDirection(modelIndex);
			return;
		}

		if (isAppendMode(event)) {
			orderProvider.appendOrder(currentPushedTitleCell.getModelIndex(),
					true);
			return;
		}

		orderProvider.setOrder(currentPushedTitleCell.getModelIndex(), true);
	}

	private void releasePushedTitleCell(IGridWidget gridWidget) {

		if (currentPushedTitleCell == null) {
			return;
		}

		currentPushedTitleCell.updateStateMask(
				~IStateMasks.SELECTED_STATE_MASK, 0);

		currentPushedTitleCell = null;
	}

}
